#include "SwfUI.h"
#include <sstream>

namespace SwfUI
{
	namespace detail
	{
		template<typename T, typename T2>
		void convert(const T& value, T2& out)
		{
			std::wstringstream ss;
			ss << value;
			ss >> out;
		}
	}

	Argument Argument::Null;

	Argument::Argument()
		:type(AT_NULL)
	{
	}

	Argument::Argument(const Argument& other)
		:type(other.type),value(other.value),stringValue(other.stringValue)
	{
	}

	Argument::Argument(float value)
		:type(AT_NUMERIC)
	{
		this->value.numeric = value;
	}

	Argument::Argument(int value)
		:type(AT_NUMERIC)
	{
		this->value.numeric = (float)value;
	}

	Argument::Argument(bool value)
		:type(AT_BOOLEAN)
	{
		this->value.boolean = value;
	}

	Argument::Argument(const std::wstring& value)
		:type(AT_STRING)
	{
		stringValue = value;
	}

	Argument::operator float() const
	{
		switch(type)
		{
		case AT_BOOLEAN:
			return value.boolean ? 1.0f : 0.0f;
		case AT_NUMERIC:
			return value.numeric;
		case AT_STRING:
			value.numeric = 0.0f;
			detail::convert(stringValue,value.numeric);
			return value.numeric;
		default:
			return 0.0f;
		}
	}

	Argument::operator bool() const
	{
		switch(type)
		{
		case AT_BOOLEAN:
			return value.boolean;
		case AT_NUMERIC:
			return value.numeric != 0.f;
		case AT_STRING:
			return stringValue == L"true";
		default:
			return false;
		}
	}

	Argument::operator const std::wstring& () const
	{
		switch(type)
		{
		case AT_BOOLEAN:
			detail::convert(value.boolean,stringValue);
			return stringValue;
		case AT_NUMERIC:
			detail::convert(value.numeric,stringValue);
			return stringValue;
		case AT_STRING:
			return stringValue;
		default:
			return stringValue;
		}
	}

	ArgumentList& ArgumentList::operator()(const Argument& arg)
	{
		push_back(arg);
		return *this;
	}

	ArgumentList::ArgumentList()
	{
	}

	ArgumentList::ArgumentList(const Argument& firstArgument)
	{
		push_back(firstArgument);
	}
}